#include "time.h"
#include "memorymanager.h"
#include "error.h"
#include "..\common\types.h"
#include <mmsystem.h>
#include <stdio.h>

/**************************************
 *
 **************************************/
CTimeDevice::CTimeDevice() : m_TotalFrames(0), m_FPS(0.0f), 
m_Second(0.0f), m_Minute(0.0f), m_Hour(0.0f), 
m_DeltaTime(0.0f), 
m_dwLastUpdateTime(0), m_dwTime(0), m_dwLastTime(0)
{
	EE_ZEROMEMORY(m_TimeStr, sizeof(m_TimeStr)); 
}

/**************************************
 *
 **************************************/
CTimeDevice::~CTimeDevice(void)
{
	EE_ZEROMEMORY(m_TimeStr, sizeof(m_TimeStr)); 
}

/**************************************
 *Destroys the timer in terms of its
 *thread running and in terms of reseting
 *the classes fields
 **************************************/
HRESULT CTimeDevice::Release()
{
	m_TotalFrames		= 0; 
	m_FPS		= 0.0f; 
	m_Second	= 0.0f; 
	m_Minute	= 0.0f; 
	m_Hour		= 0.0f; 
	m_DeltaTime	= 0.0f; 

	EE_ZEROMEMORY(m_TimeStr, sizeof(m_TimeStr)); 
	m_dwTime		= 0; 
	m_dwLastTime	= 0; 

	return S_OK;
}

/**************************************
 *SetStates the fields of this class to
 *their defaults and creates a thread in
 *a suspended state. The thread can be 
 *started so that the classes functionality
 *can be used by use of the StartThread()
 *method
 **************************************/
HRESULT CTimeDevice::Initailize()
{
	m_TotalFrames		= 0; 
	m_FPS		= 0.0f; 
	m_Second	= 0.0f; 
	m_Minute	= 0.0f; 
	m_Hour		= 0.0f; 
	m_DeltaTime	= 0.0f; 

	EE_ZEROMEMORY(m_TimeStr, sizeof(m_TimeStr)); 
	m_dwTime		= 0; 
	m_dwLastTime	= 0; 
	return S_OK;
}

/**************************************
 *Synchronizes the timer device with the
 *system to thus allow data from the timer
 *class to be used externally. The timer 
 *assumes that this function indicates the
 *system has rendered a frame
 **************************************/
void CTimeDevice::Update(void)
{
	//Update fundamental time values
	m_dwLastTime = m_dwTime; 
	m_dwTime = timeGetTime(); 
	m_DeltaTime = (float)(m_dwTime - m_dwLastTime) / 1000.0F; 

	float updateDelta = (float)(m_dwTime - m_dwLastUpdateTime) / 1000.0F; 
	m_dwLastUpdateTime = m_dwTime; 

	m_FPS = (updateDelta > 0) ? (1.0f / updateDelta) : 0.0f; 

	m_TotalFrames++; 

	//Update clock values
	m_Second += m_DeltaTime; 
	if(m_Second > 60.0F)
	{
		m_Minute += 1.0F; 
		m_Second = 0.0F; 
	}

	if(m_Minute > 60.0F)
	{
		m_Hour += 1.0F; 
		m_Minute = 0.0F; 
	}
}

/**************************************
 *Returns the FPS performance
 **************************************/
float CTimeDevice::getFPS(void)			
{ 
	return m_FPS; 
}

/**************************************
 *Returns the total seconds elapsed since
 *thread start
 **************************************/
float CTimeDevice::getElapSeconds(void)	
{ 
	return m_Second;  
}

/**************************************
 *Returns the total minutes elapsed since
 *thread start
 **************************************/
float CTimeDevice::getElapMinutes(void)	
{ 
	return m_Minute;  
}

/**************************************
 *Returns the total hours elapsed since
 *thread start
 **************************************/
float CTimeDevice::getElapHours(void)		
{ 
	return m_Hour;  
}

/**************************************
 *Returns the delta time of this threads
 *process function
 **************************************/
float CTimeDevice::GetTimeDelta(void)
{ 
	return m_DeltaTime;  
}

/**************************************
 *Returns a string representation of the
 *time in hh:mm:ss format
 **************************************/
char* CTimeDevice::GetTimeStr(void)
{
	sprintf_s(m_TimeStr, "%2i:%2i:%2.2f", (unsigned int)m_Hour, (unsigned int)m_Minute, (float)m_Second); 
	return &m_TimeStr[0]; 
}